﻿Module modMain

#Region "Global Objects"

    '* * * Developer's NOTE: This declaration is used to create an In Memory connection to a SQL Database.  
    '* * * Not used for the purpose of this demo.
    'Public myWSFObjects As New dbiWSF.FrameworkObjects.objWSFObjects(dbiWSF.Databinding.ConnectionTypes.SQLDatabase, _
    '                                                                 dbiWSF.Databinding.DataBindingMethods.InMemory, _
    '                                                                 "Data Source=DB1TECHNT2;Initial Catalog=dbiFrameworks;Integrated Security=True")


    'The objWSFObjects object is the parent object of all the other object classes created.
    'The following code will create a new instance of the WSFObjects object and load it with Warehouses, Loading Docks, 
    'Shipments, Cargo Types and Exceptions from the WSFOleDB.accdb datatabase located in the same directory as the executable.
    'The New method on the object also incepts the databinding between the objects and their physical data storage in the database.
    Public myWSFObjects As New dbiWSF.FrameworkObjects.objWSFObjects(dbiWSF.Databinding.ConnectionTypes.OLEDatabase, _
                                                                     dbiWSF.Databinding.DataBindingMethods.InMemory, _
                                                                     "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=WSFOleDB.accdb")

    'Create an instance of the business rules object and attach it to the WSFObjects
    '* * * Developer's NOTE: The Business Rules are contained in the dbiWSFSupport dll and
    '* * * are available for customization through the source code provided with the product.
    Public myBusinessRules As New dbiWSF.BusinessRulesAndSupport.BusinessRuleObjects(myWSFObjects)

    'Create an instance of the context menu user control from the dbiWSFUserInterface dll.
    '* * * Developer's NOTE: By declaring a base context menu object with events the developer
    '* * * can attach their own events to any context menu derived from the following.
    '* * * This allows for custom items in the context menu over and above the default items
    '* * * found in the context menu in the dbiWSFUserInterface dll.  See Context menu routines below.
    Public WithEvents myContextMenu As New dbiWSF.ControlLibrary.dbiWSFObjectMenu

#End Region

#Region "Global Settings"
    'The following public variables carry the style of the user controls and the type of user.
    Public curStyleName As String = My.Settings.Style
    Public LoginLevel As LoginCredentials = LoginCredentials.User
#End Region

#Region "enumerations"
    'Used to determine the audience for the demo presentation.
    Public Enum LoginCredentials
        User = 0
        Manager = 1
        Developer = 2
    End Enum
#End Region

#Region "Context menu Routines"
    'The context menu routines extend the context menu found in the dbiWSF.ControlLibrary and declared above as myContextMenu.
    'The following click events attach to the custom items added to the context menu.

    Private Sub mySchedContext_cmDetailClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectViewDetailArgs) Handles myContextMenu.cmDetailClicked
        'Display a detail dialog for the object on which the context menu has been placed.
        'NOTE: The dialog has an extended Show Method (ShowWithObject) that allows it to 
        'be called with any of the WSF Objects, i.e. Shipment, Warehouse, Exception, etc.
        Dim detailDLG As New dbiWSF.Dialogs.dlgWSFObjectDetail

        detailDLG.ShowWithObject(e.argsObject, myWSFObjects)
        detailDLG.Dispose()

        myContextMenu.TriggerUpdateDataTimer()
        'NOTE: This is required to trigger an event that signifies a change may have occurred to the data.
        '      This occurs on a separate thread to insure no other processes are interrupted when updating the data.
        'NOTE: This will also trigger a cmUpdatedData event on the context to allow for the synchronizing of other controls
        '      to changes in the data caused by the action in the context menu control.

    End Sub

    Private Sub mySchedContext_cmLoadingDockAddExceptionClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFLoadingDockAddExceptionsArgs) Handles myContextMenu.cmLoadingDockAddExceptionClicked
        'This is fired when the user selects to Add an Exception from the context menu
        MessageBox.Show("For the purpose of this demo, the ability to add LoadingDock Exceptions has been restricted to the maintenance section of the demo.", "This functionality is disabled", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End Sub

    Private Sub mySchedContext_cmLoadingDockAddShipmentClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectAddArgs) Handles myContextMenu.cmLoadingDockAddShipmentClicked
        'This is fired when the user selects to Add a Shipment from the Context Menu
        'NOTE: This method takes a WSFObjectAddArgs object as a parameter in the call.
        Try
            Dim newShipment As New dbiWSF.FrameworkObjects.objShipment(myWSFObjects)
            With newShipment
                .Description = "New Shipment"
                .LoadingDockID = e.argsLoadingDock.LoadingDockID
                .SchedStartTime = CDate("Jan 2, 2012 8:00:00AM")
                .SchedEndTime = .SchedStartTime.AddHours(1)
            End With
            newShipment.AddNew()

            'Open up a detail dialog object with the new shipment.
            Dim detailDlg As New dbiWSF.Dialogs.dlgWSFObjectDetail

            'NOTE: The detail dialog is opened with the new shipment, the base myWSFObjects, and the business rules.
            detailDlg.ShowWithObject(newShipment, myWSFObjects, myBusinessRules)

            If detailDlg.DialogResult = DialogResult.Cancel Then
                'Remove the shipment from the Loading Dock
                newShipment.Remove(e.argsLoadingDock)

            Else
                'Add the new shipment to the Loading Dock's Shipments Collection
                e.argsLoadingDock.Shipments.Add(newShipment)

                myContextMenu.TriggerUpdateDataTimer()
                'NOTE: This is required to trigger an event that signifies a change may have occurred to the data.
                '      This occurs on a separate thread to insure no other processes are interrupted when updating the data.
                'NOTE: This will also trigger a cmUpdatedData event on the context to allow for the synchronizing of other controls
                '      to changes in the data caused by the action in the context menu control.

                'Open up the Add Orders Dialog to allow the user to select either Purchase Orders (Incoming) or Sales Orders (Outgoing) to the Shipment.
                AddOrderHeaders(newShipment, e.argsLoadingDock)

            End If

        Catch ex As Exception

        End Try

    End Sub

    Private Sub mySchedContext_cmLoadingDockDeleteClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectDeleteArgs) Handles myContextMenu.cmLoadingDockDeleteClicked
        'This is fired when the user selects to delete a loading dock from a warehouse.
        e.AllowDelete = False
        MessageBox.Show("For the purpose of this demo, the ability to delete LoadingDocks as been disabled." + vbCrLf + "It is possible to hide this option from the dbiWSFObjectMenu by setting its ShowLoadingDockMaintenance property to false", "This functionality is disabled", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End Sub

    Private Sub mySchedContext_cmLoadingDockTransferToWarehouseClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectTransferEventArgs) Handles myContextMenu.cmLoadingDockTransferToWarehouseClicked
        'This is fired when a user selects to transfer a loading dock from one warehouse to another.
        e.AllowTransfer = False
        MessageBox.Show("The Transfer functionality is included to allow for handling situations where a dock's location may need to change for temporary or permanent reasons." + vbCrLf + "However for the demo, this functionality has been disabled", "This functionality is disabled", MessageBoxButtons.OK, MessageBoxIcon.Information)

    End Sub

    Private Sub myContextMenu_cmShipmentAddOrderHeaderClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectAddArgs) Handles myContextMenu.cmShipmentAddOrderHeaderClicked
        'This is fired when a user selects to add an order to the shipment.
        'Create a new instance of the Add Order Headers form.
        'NOTE: The New method has been extended to take a shipment and loading dock.
        Dim frmHeaders As New frmAddOrderHeaders(e.argsShipment, myWSFObjects.GetLoadingDockFromGUID(e.argsShipment.LoadingDockID))

        frmHeaders.ShowDialog()

        frmHeaders.Dispose()

    End Sub

#Region "Context menu extension"
    Private Sub myContextMenu_cmShipmentMenuBuilt(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectMenuCreatedArgs) _
    Handles myContextMenu.cmShipmentMenuBuilt
        'Add additional items to the Shipment Context menu, specific to my application needs
        e.ObjectMenu.DropDownItems.Add("Shipment Check In/Out", Nothing, ShipmentCheckInOutHandle)
        e.ObjectMenu.DropDownItems.Add("Shipment Confirmation", Nothing, ShipmentConfirmationHandle)
    End Sub

    Private Sub ShipmentCheckInOut(ByVal sender As Object, ByVal e As System.EventArgs)
        MessageBox.Show("Here you could add integration to your current systems to handle Checking in and out the various shipments, allowing " + _
                        "you to keep track of the actual time the trucks and their cargo occupy a loading dock.  As well you can also use this " + _
                        "to handle load discrepancies in any of the orders, allowing you to track and report these to your suppliers or " + _
                        "customers.", "Shipment Check In/Out and Discrepancies", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    Private Sub ShipmentConfirmation(ByVal sender As Object, ByVal e As System.EventArgs)
        MessageBox.Show("Here you could add integration to your current system, or add new functionality, to allow you to directly communicate " + _
                        "with the drivers and clients, when a Shipment has been confirmed. This confirmation could go out as a e-mail, " + _
                        "automated phone call, text message, or any other means that fit your applications and operations requirements.", _
                        "Shipment Confirmation", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    'Event Handlers to allow me to fire custom code when a user clicks on one of my custom Context menu items.
    Private ShipmentCheckInOutHandle As New System.EventHandler(AddressOf ShipmentCheckInOut)
    Private ShipmentConfirmationHandle As New System.EventHandler(AddressOf ShipmentConfirmation)
#End Region

    Private Sub mySchedContext_cmWarehouseAddLoadingDockClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectAddArgs) Handles myContextMenu.cmWarehouseAddLoadingDockClicked
        Try
            Dim newLoadingDock As New dbiWSF.FrameworkObjects.objLoadingDock(myWSFObjects)
            With newLoadingDock
                .Description = "New Dock"
                .WarehouseID = e.argsWarehouse.WarehouseID
                .WarehouseOrdinal = e.argsWarehouse.GetNextLoadingDockWarehouseOrdinal
            End With
            newLoadingDock.AddNew()

            Dim detailDlg As New dbiWSF.Dialogs.dlgWSFObjectDetail
            detailDlg.ShowWithObject(newLoadingDock, myWSFObjects, myBusinessRules)

            If detailDlg.DialogResult = DialogResult.Cancel Then
                newLoadingDock.Remove(e.argsWarehouse)
            Else
                myContextMenu.TriggerUpdateDataTimer()
            End If
        Catch ex As Exception

        End Try
    End Sub

    Private Sub mySchedContext_cmWarehouseDeleteClicked(ByVal sender As Object, ByVal e As dbiWSF.ControlLibrary.dbiWSFObjectMenu.WSFObjectDeleteArgs) Handles myContextMenu.cmWarehouseDeleteClicked
        e.AllowDelete = False
        MessageBox.Show("For the purpose of this demo, the ability to delete Warehouses as been disabled." + vbCrLf + "It is possible to hide this option from the dbiWSFObjectMenu by setting its ShowWarehouseMaintenance property to false", "This functionality is disabled", MessageBoxButtons.OK, MessageBoxIcon.Information)
    End Sub

    Public Sub AddOrderHeaders(ByRef Shipment As dbiWSF.FrameworkObjects.objShipment, ByRef LoadingDock As dbiWSF.FrameworkObjects.objLoadingDock)
        Dim frmHeaders As New frmAddOrderHeaders(Shipment, LoadingDock)
        frmHeaders.ShowDialog()
        frmHeaders.Dispose()
        myContextMenu.TriggerUpdateDataTimer()
    End Sub
#End Region

#Region "NorthWinds Purchase Order and Sales Data"
    'The following code connects the Warehouse Shipments Framework to a sample Purchase Order and Sales Order System
    'derived from the Northwinds database.  This simulates integration of the Warehouse Shipments Framework into an
    'organization's database running a Purchase Order and Sales system.
    'NOTE: The data is designed to represent classic organizational PO and Sales system data.
    Public adoNorthwindConnStr As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=SampleBinding.accdb"

    'Set up a data adapter and a data table to bind the Products Table from the Northwinds database.
    Public daProducts As Data.OleDb.OleDbDataAdapter
    Public dtProducts As New DataTable("Products")
    'Create a collection of Northwind Product objects (See declaration below) 
    Public collProducts As New Collections.Generic.List(Of NorthwindProduct)

    'Create a data adapter to connect the physical Order Header (Invoice Header) data to the data table in memory.
    Public daOrders As Data.OleDb.OleDbDataAdapter
    'Create a data table to store the Order Header data in memory.
    Public dtOrders As New DataTable("Orders")

    'Create a data adapter to connect the physical Order Details (Invoice Details) data to the data table in memory.
    Public daOrderDetails As Data.OleDb.OleDbDataAdapter
    'Create a data table to store the Order Detail data in memory.
    Public dtOrderDetails As New DataTable("OrderDetails")

    'Create a data adapter to connect the physical Purchase Order Header data to the data table in memory.
    Public daPurchaseOrders As Data.OleDb.OleDbDataAdapter
    'Create a data table to store the Purchase Order Header data in memory.
    Public dtPurchaseOrders As New DataTable("PurchaseOrders")

    'Create a data adapter to connect the physical Purchase Order Detail data to the data table in memory.
    Public daPODetails As Data.OleDb.OleDbDataAdapter
    'Create a data table to store the Purchase Order Detail data in memory.
    Public dtPODetails As New DataTable("PODetails")

    'Create a data adapter to connect the physical Shipper (Trucking companies, etc.) data to the data table in memory.
    Public daShippers As Data.OleDb.OleDbDataAdapter
    'Create a data table to store the Shipper data in memory.
    Public dtShippers As New DataTable("Shippers")

    Public UnassignedOrderHeaders As New System.Collections.Generic.List(Of dbiWSF.FrameworkObjects.objOrderHeader)

    'Declare an object to describe a product that is ordered or sold.
    'NOTE: This will provide an object description of the data in the Products table from the Northwinds database.
    Public Class NorthwindProduct
        Public ProdID As Long
        Public ProductCode As String
        Public ProductName As String
        Public ListPrice As Double
        Public QuantityPerUnit As String
        Public WeightInLbs As String
        Public Category As String
        Public CargoType As Guid
    End Class

    Public Sub LoadProductsFromNorthwind()
        'A subroutine to load the products from the Northwinds database.
        'Create a data adapter to attach to the Products table in the database to the application.
        daProducts = New OleDb.OleDbDataAdapter("Select * from Products", adoNorthwindConnStr) '
        'Create a command builder to operate on the data adapter.
        Dim dcbProducts As New OleDb.OleDbCommandBuilder(daProducts)
        daProducts.MissingSchemaAction = MissingSchemaAction.AddWithKey

        'Use the data adapter to fill the data table declared public above.
        daProducts.Fill(dtProducts)

        'Cycle through the products in the Products table and add them to the Products Collection
        For Each curRow As DataRow In dtProducts.Rows
            Dim newProd As New NorthwindProduct
            With newProd
                .ProdID = curRow("ID")
                .ProductCode = curRow("Product Code")
                .ProductName = curRow("Product Name")
                .ListPrice = curRow("List Price")
                .QuantityPerUnit = curRow("Quantity Per Unit")
                .WeightInLbs = curRow("WeightInLbs")
                .Category = curRow("Category")
                .CargoType = curRow("CargoType")
            End With
            collProducts.Add(newProd)
        Next

    End Sub

    Public Sub LoadShippers()
        'A subroutine to the load the shippers from the Northwinds database.
        'Create a data adapter to attach the Shippers table in the database to the application.
        daShippers = New OleDb.OleDbDataAdapter("Select * from Shippers", adoNorthwindConnStr)
        'Create a command builder to operate on the data adapter.
        Dim dcbShippers As New OleDb.OleDbCommandBuilder(daShippers)
        daShippers.MissingSchemaAction = MissingSchemaAction.AddWithKey

        'Use the data adapter to fill the data table declared public above
        daShippers.Fill(dtShippers)

    End Sub

    Public Sub LoadOrders()
        'A subroutine to load the Sales and Purchase Orders along with their details from the Northwinds database.

        'Create a data adapter to attach the Orders table in the database to the application.
        daOrders = New Data.OleDb.OleDbDataAdapter("Select * From Orders", adoNorthwindConnStr)
        'Create a command builder to operate on the data adapter.
        Dim dcbOrders As New Data.OleDb.OleDbCommandBuilder(daOrders)
        daOrders.MissingSchemaAction = MissingSchemaAction.AddWithKey
        'Use the data adapter to fill the data table declared public above
        daOrders.Fill(dtOrders)

        'Create a data adapter to attach the PurchaseOrders table in the database to the application.
        daPurchaseOrders = New Data.OleDb.OleDbDataAdapter("Select * From PurchaseOrders", adoNorthwindConnStr)
        'Create a command builder to operate on the data adapter.
        Dim dcbPurchaseOrders As New Data.OleDb.OleDbCommandBuilder(daPurchaseOrders)
        daPurchaseOrders.MissingSchemaAction = MissingSchemaAction.AddWithKey
        'Use the data adapter to fill the data table declared public above
        daPurchaseOrders.Fill(dtPurchaseOrders)

        'Create a data adapter to attach the OrderDetails table in the database to the application.
        daOrderDetails = New Data.OleDb.OleDbDataAdapter("Select * From OrderDetails", adoNorthwindConnStr)
        'Create a command builder to operate on the data adapter.
        Dim dcbOrderDetails As New Data.OleDb.OleDbCommandBuilder(daOrderDetails)
        daOrderDetails.MissingSchemaAction = MissingSchemaAction.AddWithKey
        'Use the data adapter to fill the data table declared public above
        daOrderDetails.Fill(dtOrderDetails)

        'Create a data adapter to attach the PurchaseOrderDetails table in the database to the application.
        daPODetails = New Data.OleDb.OleDbDataAdapter("Select * From PurchaseOrderDetails", adoNorthwindConnStr)
        'Create a command builder to operate on the data adapter.
        Dim dcbPODetails As New Data.OleDb.OleDbCommandBuilder(daPODetails)
        daPODetails.MissingSchemaAction = MissingSchemaAction.AddWithKey
        'Use the data adapter to fill the data table declared public above
        daPODetails.Fill(dtPODetails)

    End Sub

    Public Function GetProductByID(ByVal ProdID As Long) As NorthwindProduct
        'A function to look up and return a Northwind Product object from the collProducts collection 
        'based on its ProdID value
        Dim curProduct As NorthwindProduct

        'Construct a LINQ statement to return all NorthwindProduct objects with the specified ProdID value.
        'NOTE: The ProdID is unique in the table and therefore in the collProducts collection,
        '      therefore only one product will be returned.

        Dim linqGetProduct = From Product As NorthwindProduct In collProducts _
                             Where Product.ProdID = ProdID _
                             Select Product

        If linqGetProduct.Count = 0 Then    'The LINQ statement did not return any objects.

            curProduct = Nothing

        Else    'The LINQ statement returned at least one object

            'NOTE: The LINQ statement returns a collection of NorthwindProduct objects.
            '      Return the first object (0) in the collection.
            curProduct = linqGetProduct(0)

        End If

        Return curProduct

    End Function

#End Region

End Module
